package com.zhx.real.mybatisplus.business;

import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 *describe: 树形的结构树整理
 *
 *@author zhanghaixuan
 *@date 2018/09/20
 **/
public class TreeEntityUtil {

	/**
	 * 使用递归方法建树
	 *
	 * @param treeNodes 列表
	 * @return 树形结构
	 */
	public static <T extends TreeEntity> List<T> buildByRecursive(List<T> treeNodes, String root) {

		if(StringUtils.isEmpty(root)) {
			root = findRoot(treeNodes);
		}

		List<T> trees = new ArrayList<>();
		for(T treeNode : treeNodes) {
			if(root.equals(treeNode.getParentId())) {
				treeNode.setFullTitle(treeNode.getName());
				trees.add(findChildren(treeNode, treeNodes));
			}
		}
		return trees;
	}

	/**
	 * 递归查找子节点
	 *
	 * @param treeNodes 全部列表
	 * @return 寻找当前的子节点
	 */
	private static <T extends TreeEntity> T findChildren(T treeNode, List<T> treeNodes) {
		for(T it : treeNodes) {
			if(treeNode.getUid().equals(it.getParentId())) {

				if(treeNode.getChildren().size() < 1) {
					treeNode.setChildren(new ArrayList<TreeEntity>());
				}

				it.setFullTitle(treeNode.getFullTitle() + it.getName());
				treeNode.add(findChildren(it, treeNodes));
			}
		}

		if(treeNode.getChildren().size() < 1) {
			treeNode.setBottom(true);
		}

		return treeNode;
	}

	/**
	 * 查找当前树的根节点
	 * @param nodeList 全部数据
	 * @return 根节点
	 **/
	private static <T extends TreeEntity> String findRoot(List<T> nodeList) {
		if(nodeList.size() == 0) {
			return "";
		}

		boolean tempValue = true;

		String pid = nodeList.get(0).getParentId();

		while(tempValue) {
			String tempPraentId = findPid(nodeList, pid);
			if(StringUtils.isNotEmpty(tempPraentId)) {
				pid = tempPraentId;
			} else {
				tempValue = false;
			}
		}



		return pid;
	}

	/**
	 * 循环查找是否有对应的父节点
	 * @param nodeList 全部数据
	 * @param parentId 当前查到的父节点Id
	 * @return 查找到的父节点Id
	 */
	private static <T extends TreeEntity> String findPid(List<T> nodeList, String parentId) {
		for(T t : nodeList) {
			if(t.getUid().equals(parentId)) {
				return t.getParentId();
			}
		}

		return "";
	}

}
